package com.ssyt.hiring.common.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.ssyt.hiring.talent.entity.TalentEntity;

public class ReflectionTest1 {

	public static void main(String[] args) throws ClassNotFoundException,
			NoSuchMethodException, SecurityException, InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchFieldException {
		// test1();
		// test2();
		// test3();
		// test4();
		// test5();
		test6();
	}

	/**
	 * 获得Class对象（3种方式）
	 */
	public static void test1() {
		// 第一种
		Class<?> clazz = TalentEntity.class;
		// System.out.println(clazz.getName());
		// System.out.println(clazz.getSimpleName());
		// System.out.println(clazz.getSuperclass().getName());
		// System.out.println(clazz);

		// 第二种
		// TalentEntity talentEntity = new TalentEntity();
		// System.out.println(talentEntity.getClass());

		// 第三种
		try {
			Class<?> forName = Class
					.forName("com.ssyt.hiring.talent.entity.TalentEntity");
			System.out.println(forName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 通过反射的方式去实例化对象
	 * 
	 * @throws ClassNotFoundException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static void test2() throws ClassNotFoundException,
			NoSuchMethodException, SecurityException, InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		Class<?> clazz = Class
				.forName("com.ssyt.hiring.talent.entity.TalentEntity");
		// 反射在实例化时调用的是空的构造方法
		// TalentEntity talentEntity = (TalentEntity) clazz.newInstance();
		// 反射使用指定的构造方法实例化对象
		Constructor<?> constructor = clazz.getConstructor(int.class);
		TalentEntity talentEntity = (TalentEntity) constructor.newInstance(110);
		System.out.println(talentEntity.getId());
	}

	/**
	 * 使用反射让单例模式不复存在
	 * 
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	public static void test3() throws InstantiationException,
			IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchMethodException, SecurityException {
		Class<?> clazz = Singleton.class;
		for (int i = 0; i < 10; i++) {
			// clazz.getDeclaredConstructor
			// 能访问类的所有构造方法，包括私有的，如果要访问private的一定要注意使用setAccessiable开启权限
			// clazz.getConstructor 能访问类的所有非私有的构造方法
			Constructor<?> declaredConstructor = clazz.getDeclaredConstructor();
			declaredConstructor.setAccessible(true);
			Singleton singleton = (Singleton) declaredConstructor.newInstance();
			System.out.println(singleton);
		}
	}

	/**
	 * 获取类对象的所有构造方法、一般方法、成员变量
	 */
	public static void test4() {
		Class<?> clazz = TalentEntity.class;
		Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
		for (Constructor<?> constructor : declaredConstructors) {
			System.out.println("构造方法：" + constructor);
		}

		Method[] declaredMethods = clazz.getDeclaredMethods();
		for (Method method : declaredMethods) {
			System.out.println("一般方法：" + method);
		}

		Field[] declaredFields = clazz.getDeclaredFields();
		for (Field field : declaredFields) {
			System.out.println("成员变量：" + field.getName());
		}
	}

	/**
	 * 把私有的属性赋值
	 * 
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static void test5() throws NoSuchFieldException, SecurityException,
			InstantiationException, IllegalAccessException {
		Class<?> clazz = TalentEntity.class;
		TalentEntity talentEntity = (TalentEntity) clazz.newInstance();
		Field declaredField = clazz.getDeclaredField("id");
		declaredField.setAccessible(true);
		declaredField.setInt(talentEntity, 1);
		System.out.println(talentEntity.getId());
	}

	/**
	 * 方法的调用
	 * 
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	public static void test6() throws InstantiationException,
			IllegalAccessException, NoSuchMethodException, SecurityException,
			IllegalArgumentException, InvocationTargetException {
		Class<?> clazz = TalentEntity.class;
		TalentEntity talentEntity = (TalentEntity) clazz.newInstance();
		Method setterMethod = clazz.getMethod("setId", int.class);
		setterMethod.invoke(talentEntity, 123);
		Method getterMethod = clazz.getMethod("getId");
		Object returnObj = getterMethod.invoke(talentEntity);
		System.out.println(returnObj);
	}
}
